package com.ruoyi.qd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.func.LambdaUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.qd.domain.Robot;
import com.ruoyi.qd.domain.RobotQueue;
import com.ruoyi.qd.enums.RobotEnableStatusEnum;
import com.ruoyi.qd.enums.RobotOnlineStatusEnum;
import com.ruoyi.qd.enums.RobotQueueStatusEnum;
import com.ruoyi.qd.mapper.RobotMapper;
import com.ruoyi.qd.service.IRobotService;
import com.ruoyi.qd.vo.RobotListUsableRes;
import com.ruoyi.qd.vo.RobotPageRes;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.domain.entity.table.SysDeptTableDef.SYS_DEPT;
import static com.ruoyi.qd.domain.table.RobotQueueTableDef.ROBOT_QUEUE;
import static com.ruoyi.qd.domain.table.RobotTableDef.ROBOT;


/**
 * 机器人Service业务层处理
 *
 * @author tushiguang
 * @date 2024-07-23
 */
@Service
public class RobotServiceImpl extends ServiceImpl<RobotMapper, Robot> implements IRobotService {
    @Override
    public List<RobotListUsableRes> listUsable() {
        List<Robot> robotList = Robot.create()
                .where(Robot::getEnableStatus).eq(RobotEnableStatusEnum.YES.getCode())
                .and(Robot::getOnlineStatus).eq(RobotOnlineStatusEnum.YES.getCode())
                .and(ROBOT.DEPT_ID.in(
                        QueryMethods.select(SYS_DEPT.DEPT_ID).from(SYS_DEPT)
                                .where(SYS_DEPT.DEPT_ID.eq(SecurityUtils.getChooseDeptId())
                                        .or(SYS_DEPT.PARENT_ID.eq(SecurityUtils.getChooseDeptId())))
                ))
                .orderBy(Robot::getId).asc()
                .list();
        List<RobotListUsableRes> robotListUsableRes = BeanUtil.copyToList(robotList, RobotListUsableRes.class);
        Map<Long, RobotListUsableRes> robotIdToRobotListUsableResMap = robotListUsableRes.stream()
                .collect(Collectors.toMap(RobotListUsableRes::getId, Function.identity()));

        String robotId = ROBOT_QUEUE.ROBOT_ID.getName();
        String todayAppointmentNumber = LambdaUtil.getFieldName(RobotListUsableRes::getTodayAppointmentNumber);
        DbChain.table(ROBOT_QUEUE)
                .select(ROBOT_QUEUE.ROBOT_ID, QueryMethods.count().as(todayAppointmentNumber))
                .where(QueryMethods.date(ROBOT_QUEUE.APPOINTMENT_TIME).eq(QueryMethods.curDate()))
                .and(ROBOT_QUEUE.STATUS.eq(RobotQueueStatusEnum.LINE.getCode()))
                .groupBy(RobotQueue::getRobotId)
                .list()
                .forEach(row -> {
                    robotIdToRobotListUsableResMap.get((Long)row.get(robotId))
                            .setTodayAppointmentNumber((Long)row.get(todayAppointmentNumber));
                });

        // 根据 robotListUsableRes 的 todayAppointmentNumber 从小到大排序
        robotListUsableRes.sort(Comparator.comparing(RobotListUsableRes::getTodayAppointmentNumber));
        return robotListUsableRes;
    }

    /**
     * 查询机器人
     *
     * @param id 机器人主键
     * @return 机器人
     */
    @Override
    public Robot selectRobotById(Long id) {
        return mapper.selectOneById(id);
    }

    @Override
    public Page<RobotPageRes> selectRobotPage(PageDomain pageDomain, Robot robot) {
        return Robot.create()
                .select(ROBOT.ALL_COLUMNS, SYS_DEPT.DEPT_NAME)
                .leftJoin(SYS_DEPT).on(SYS_DEPT.DEPT_ID.eq(ROBOT.DEPT_ID))
                .where(ROBOT.SN.eq(robot.getSn()))
                .and(ROBOT.DEPT_ID.in(
                        QueryMethods.select(SYS_DEPT.DEPT_ID).from(SYS_DEPT)
                        .where(SYS_DEPT.DEPT_ID.eq(robot.getDeptId())
                                .or(SYS_DEPT.PARENT_ID.eq(robot.getDeptId())))
                        )
                )
                .and(ROBOT.TITLE.like(robot.getTitle()))
                .and(ROBOT.ONLINE_STATUS.eq(robot.getOnlineStatus()))
                .and(ROBOT.ENABLE_STATUS.eq(robot.getEnableStatus()))
                .pageAs(new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize()), RobotPageRes.class);
    }

    /**
     * 查询机器人列表
     *
     * @return 机器人
     */
    @Override
    public List<RobotPageRes> selectRobotList() {
        return Robot.create()
                .select(ROBOT.ALL_COLUMNS, SYS_DEPT.DEPT_NAME)
                .leftJoin(SYS_DEPT).on(SYS_DEPT.DEPT_ID.eq(ROBOT.DEPT_ID))
                .listAs(RobotPageRes.class);
    }

    /**
     * 查询机器人列表
     *
     * @param robot 机器人
     * @return 机器人
     */
    @Override
    public List<Robot> selectRobotList(Robot robot) {
        QueryWrapper query = buildWrapper(robot);
        return mapper.selectListByQuery(query);
    }

    public QueryWrapper buildWrapper(Robot robot) {
        return query()
                .where(ROBOT.SN.eq(robot.getSn()))
                .and(ROBOT.IMAGE.eq(robot.getImage()))
                .and(ROBOT.PRICE.eq(robot.getPrice()))
                .and(ROBOT.ONLINE_STATUS.eq(robot.getOnlineStatus()))
                .and(ROBOT.ENABLE_STATUS.eq(robot.getEnableStatus()))
                .and(ROBOT.CREATE_BY.eq(robot.getCreateBy()))
                .and(ROBOT.UPDATE_BY.eq(robot.getUpdateBy()));
    }

    /**
     * 新增机器人
     *
     * @param robot 机器人
     * @return 结果
     */
    @Override
    public int insertRobot(Robot robot) {
        return mapper.insertSelective(robot);
    }

    /**
     * 修改机器人
     *
     * @param robot 机器人
     * @return 结果
     */
    @Override
    public int updateRobot(Robot robot) {
        return mapper.update(robot);
    }

    /**
     * 批量删除机器人
     *
     * @param ids 需要删除的机器人主键
     * @return 结果
     */
    @Override
    public int deleteRobotByIds(Long[] ids) {
        return mapper.deleteBatchByIds(Arrays.asList(ids));
    }

    /**
     * 删除机器人信息
     *
     * @param id 机器人主键
     * @return 结果
     */
    @Override
    public int deleteRobotById(Long id) {
        return mapper.deleteById(id);
    }
}
